//
// Created by wang on 2021/6/29.
//

#ifndef ENET_ARP_H
#define ENET_ARP_H

/* TODO: The INTERVACE-type header file should
 * contain only INTERFACE-type variables declarations.*/
#include "eth.h"
#include "uthash.h"

#define HW_TYPE_ETHERNET 0x0001
#define IP_PROTOCOL_V4 0x0800

#define ARP_OP_REQUEST 1
#define ARP_OP_REPLY   2

typedef struct {
    eth_header eth;
    word hrd;
    word pro;
    byte hln;
    byte pln;
    word op;
}arp_header;

#define SENDER_MAC_OFFSET sizeof(arp_header)
#define SENDER_IP_OFFSET(header) (SENDER_MAC_OFFSET + ((header).hln))
#define TARGET_MAC_OFFSET(header) (SENDER_IP_OFFSET(header) + ((header).pln))
#define TARGET_IP_OFFSET(header) (TARGET_MAC_OFFSET(header) + ((header).hln))
#define SENDER_MAC(chain) ((byte*)((chain) + SENDER_MAC_OFFSET))
#define SENDER_IP(chain, header) ((struct in_addr *)((chain) + SENDER_IP_OFFSET(header)))
#define TARGET_MAC(chain, header) ((byte*)((chain) + TARGET_MAC_OFFSET(header)))
#define TARGET_IP(chain, header) ((struct in_addr *)((chain) + TARGET_IP_OFFSET(header)))

typedef struct {
    struct in_addr ipaddr;
#define ARP_H_KEY ipaddr.s_addr
    mac m;
    UT_hash_handle hh;
}trans_entry;
#define TO_ARP_H_KEY(x) ((x).s_addr)

ret_t arp_in(rx_chain *chain);
ret_t arp_send_reply(struct in_addr dst_ip, mac dst_mac);

#define ARP_RET_ERROR (-1)
#endif //ENET_ARP_H
